//
//  WBStatusViewModel.swift
//  simpleWeibo
//
//  Created by sunmumu on 2018/10/7.
//  Copyright © 2018年 孙林. All rights reserved.
//

import Foundation

/**
 如果没有任何父类 如果希望在开发时调试 输出调试信息 需要
 1 遵守 CustomStringConvertible 协议
 2 实现 description 计算型属性
 
 关于表格的性能优化wa
 -尽量少计算 所有需要的素材提前计算好
 -控件上 不要设置圆角半径 图像渲染的属性 都要注意
 -不要动态创建控件 所有需要的控件 都要提前创建好 在显示的时候 根据数据隐藏/显示
 -cell 中 控件的层次越少越好 数量越少越好
 -要测量 不要估算
 */
class WBStatusViewModel: CustomStringConvertible {
    
    /// 微博模型
    var status: WBStatus
    /// 会员图标 计算型属性/存储型属性(用内存换CPU)
    var memberIcon: UIImage?
    /// 认证图标 -1 没有认证 0认证用户 2,3,5企业认证 228达人
    var vipIcon: UIImage?
    var retweetedString: String?
    var commendString: String?
    var likeString: String?
    /// 配图视图的大小
    var pictureViewSize = CGSize()
    /// 如果是被转发的微博, 原创微博一定没有图
    var picURLs: [WBStatusPicture]? {
        // 如果有被转发的微博, 返回被转发微博的配图
        // 如果没有被转发的微博, 返回原创微博的配图
        // 如果都没有, 返回nil
        return status.retweeted_status?.pic_urls ?? status.pic_urls
    }
    
    /// 微博正文的属性文本
    var statusAttrText: NSAttributedString?
    /// 被转发微博的属性文字
    var retweetedAttrText: NSAttributedString?
    
    /// 行高
    var rowHeight: CGFloat?
    
    
    /// 构造函数
    ///
    /// - Parameter model: 微博模型
    init(model: WBStatus) {
        self.status = model
        if (model.user?.mbrank)! > 0 && (model.user?.mbrank)! < 7 {
            let imageName = "common_icon_membership_level\(model.user?.mbrank ?? 1)"
            memberIcon = UIImage.init(named: imageName)
        }
        switch model.user?.verified_type ?? -1 {
        case 0:
            vipIcon = UIImage.init(named: "avatar_vip")
        case 2,3,5:
            vipIcon = UIImage.init(named: "avatar_enterprise_vip")
        case 228:
            vipIcon = UIImage.init(named: "avatar_grassroot")
        default:
            break
        }
        model.reposts_count = Int(arc4random_uniform(100000))
        retweetedString = countString(count: model.reposts_count, defaultString: "转发")
        commendString = countString(count: model.comments_count, defaultString: "评论")
        likeString = countString(count: model.attitudes_count, defaultString: "赞")
        // 计算配图视图大小 (有原创的就计算原创的 有转发的就计算转发的)
        pictureViewSize = calcPictureViewSize(count: picURLs?.count)
        
        // -- 设置微博属性文本 --
        let orginalFont = UIFont.systemFont(ofSize: 15)
        let forwardFont = UIFont.systemFont(ofSize: 14)
        
        // 设置微博正文的属性文本
        statusAttrText = CZEmoticonManager.shared.emoticonString(string: model.text ?? "", font: orginalFont)
        
        // 设置被转发微博的文字
        let retweetedName = (status.retweeted_status?.user?.screen_name ?? "")
        let rText = "@"
            + retweetedName
            + ":"
            + (status.retweeted_status?.text ?? "")
        
        retweetedAttrText = CZEmoticonManager.shared.emoticonString(string: rText, font: forwardFont)
        
        //计算行高
        updateRowHeight()
    }
    
    var description: String {
        return status.description
    }
    
    // 根据当前的视图模型内容 计算行高
    func updateRowHeight() {
        //原创微博 顶部分隔视图(12) + 间距(12) + 图像的高度(34) + 间距(12) + 正文高度(需要计算) + 配图视图高度(需要计算) + 间距(12) + 底部视图高度(35)
        
        //被转发微博 顶部分隔视图(12) + 间距(12) + 图像的高度(34) + 间距(12) + 正文高度(需要计算) +  间距(12) + 间距(12) + 转发微博正文高度(需要计算) +  配图视图高度(需要计算) + 间距(12) + 底部视图高度(35)
        
        let margin: CGFloat = 12
        let iconHeight: CGFloat = 34
        let toolbarHeight: CGFloat = 35
        
        var height: CGFloat = 0
        
        let viewSize = CGSize(width: (UIScreen.cz_screenWidth() - 2 * margin), height: CGFloat(MAXFLOAT))
        
        //1 计算顶部位置
        height = 2 * margin + iconHeight + margin
        //2 计算微博正文高度
        if let text = statusAttrText {
            /*
             1> 预期尺寸 宽度固定 高度尽量大
             2> 选型 换行文本 统一使用 usesLineFragmentOrigin
             3> attributes: 指定字体字典
             */
            height += text.boundingRect(with: viewSize, options: [.usesLineFragmentOrigin], context: nil).height
        }
        
        //3 判断是否转发微博
        if status.retweeted_status != nil {
            height += 2 * margin
            
            //转发文本的高度 一定用retweetedAttrText, 拼接了 @用户名: 微博文字
            if let text = retweetedAttrText {
                height += text.boundingRect(with: viewSize, options: [.usesLineFragmentOrigin], context: nil).height
            }
        }
        //4 配图视图高度
        height += pictureViewSize.height
        height += margin
        //5 底部工具栏
        height += toolbarHeight
        
        //6 属性赋值
        rowHeight = height
    }
    
    // 使用单个图像 更新配图视图的大小
    func updateSignleImageSize(image: UIImage) {
        var size = image.size
        
        //过宽图像处理
        let maxWidth: CGFloat = 300
        let minWidth: CGFloat = 40
        if size.width > maxWidth {
            //设置最大宽度
            size.width = maxWidth
            size.height = size.width * image.size.height / image.size.width
        }
        //过窄图像处理
        if size.width < minWidth {
            //设置最小宽度
            size.width = minWidth
            //要特殊处理高度 否则高度太大 会印象用户体验
            size.height = size.width * image.size.height / image.size.width / 4
        }
        
        //注意 尺寸需要增加顶部的 12个点 便于布局
        size.height += WBStatusPictureViewOutterMargin
        pictureViewSize = size
        
        updateRowHeight()
    }
    
    func calcPictureViewSize(count: Int?) -> (CGSize) {
        //1排除配图个数 为0 或为nil
        if count == 0 || count == nil {
            return CGSize()
        }
        
        //2计算配图视图的宽度
        //3计算每个item的宽度
        
        //4计算配图视图的高度
        //1) 计算行数
        let row = (count! - 1) / 3 + 1
        //2) 根据行数计算高度
        var WBStatusPictureViewHeight = WBStatusPictureViewOutterMargin
        WBStatusPictureViewHeight += CGFloat(row) * WBStatusPictureItemWidth
        WBStatusPictureViewHeight += CGFloat(row - 1) * WBStatusPictureViewInnerMargin
        
        return CGSize(width: WBStatusPictureViewWidth, height: WBStatusPictureViewHeight)
        
    }
    
    /// 给一个数字, 返回对应描述的文字
    ///
    /// - Parameters:
    ///   - count: 数字
    ///   - defaultString: 默认文字 转发/评论/点赞
    /// - Returns: 对应描述的文字
    /**
     如果数量 == 0，显示默认标题
     如果数量超过 10000，显示 x.xx 万
     如果数量 < 10000，显示实际数字
     */
    func countString(count: Int, defaultString: String) -> String {
        if count == 0 {
            return defaultString
        }
        if count < 10000 {
            return "\(count)"
        }
        return String(format: "%.02f 万", Double(count) / 10000)
    }
    
}
